package com.zmzncs.lmtc.common.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zmzncs.lmtc.common.pojo.Rest;
import com.zmzncs.lmtc.common.pojo.enums.RestCodeEnum;
import com.zmzncs.lmtc.common.util.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@Configuration
@WebFilter(filterName ="tokenFilter", urlPatterns = "/*")
@Order(value = 2)
@Slf4j
public class TokenFilter implements Filter {

    static Set requestURI = new HashSet<>(Arrays.asList(
            "/sysUser/login", "/system/user/login", "/customer/info/transfers-to-user",
            "/doc.html", "/swagger-resources", "/v2/api-docs", "/favicon.ico"
        )
    );

    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(requestURI);

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("过滤器-token-初始化");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        Rest rest = new Rest();

        //**********************************token
        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
        if (ALLOWED_PATHS.contains(path)) {
            chain.doFilter(request, response);
        }else if( path.contains("/webjars/") || path.contains("/websocket") || path.contains("/swagger-resources/") ){
            chain.doFilter(request, response);
        }else {
            //从请求头中获取token
            String token = request.getHeader("token");
            if(StringUtils.isNotBlank(token)){
                try {
                    JwtUtil.parseJWT(request);

                    chain.doFilter(request, response);
                } catch (ExpiredJwtException e){
                    log.warn("token过期");
                    rest.setCode(RestCodeEnum.CODE_401.getCode()).setDesc("登录过期，请重新登陆");
                    output(rest, response);
                } catch (MalformedJwtException e) {
                    log.warn("token不合法");
                    rest.setCode(RestCodeEnum.CODE_401.getCode()).setDesc("token不合法");
                    output(rest, response);
                }
            }else {
                log.warn(path + "的token不能为空");
                rest.setCode(RestCodeEnum.CODE_401.getCode()).setDesc("token不能为空");
                output(rest, response);
            }
        }
    }

    @Override
    public void destroy() {
        log.info("过滤器-token-销毁");
    }

    public void output(Rest Rest, HttpServletResponse response) {
        response.setContentType("application/json; charset=UTF-8;");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            // jackson核心对象
            ObjectMapper objectMap = new ObjectMapper();
            objectMap.writeValue(out, Rest);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }
    }

}